﻿using System;
using System.Collections.Generic;
using System.Linq;
using Crossroad.OAuth.Service;
using Crossroad.System.User.Model;
using Crossroad.Core.Data;
using Crossroad.Core.Exceptions;
using Crossroad.Utils.Extensions;
using Crossroad.Core.Models;
using SqlSugar;

namespace Crossroad.System.User.Service.Impl
{
    /// <summary>
    /// 平台用户 user_app
    /// </summary>
    public class UserAppService: Access<UserApp>, IUserAppService
    {
        private readonly IAccessTokenService accessTokenService;
        private readonly UserInfoService userInfoService;

        public UserAppService(
            IAccessTokenService accessTokenServiceIpt,
            IUserInfoService userInfoServiceIpt
        )
        {
            accessTokenService = accessTokenServiceIpt;
            userInfoService = userInfoServiceIpt as UserInfoService;
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="method"></param>
        /// <param name="loadRelevantData">是否加载关联数据</param>
        public Pagination<UserApp> GetPaging(
            int pageIndex,
            int pageSize,
            Action<ISugarQueryable<UserApp>> method,
            bool loadRelevantData = true
        )
        {
            var query = db.Queryable<UserApp>();
            method(query);
            var totalCount = 0;
            var page = new Pagination<UserApp>
            {
                PageIndex = pageIndex,
                PageSize = pageSize,
            };
            page.Records = query.ToPageList(page.PageIndex, page.PageSize, ref totalCount);
            page.TotalCount = totalCount;
            if (loadRelevantData)
                Load(page.Records);

            return page;
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="method"></param>
        /// <param name="loadRelevantData">是否加载关联数据</param>
        public Pagination<UserInfo> GetPaging(
            UserApp userApp,
            int pageIndex,
            int pageSize,
            Action<ISugarQueryable<UserApp, UserInfo>> method,
			bool loadRelevantData = true
        )
        {
            var query = db.Queryable<UserApp, UserInfo>((a, b) => new object[] { JoinType.Left, a.userId == b.id });
            method(query);
            var totalCount = 0;
            var page = new Pagination<UserInfo>
            {
                PageIndex = pageIndex,
                PageSize = pageSize,
            };
            page.Records = new List<UserInfo>();
            var list = query.Select((a, b) => new { user = b, a.roleId, a.organizationId }).ToPageList(page.PageIndex, page.PageSize, ref totalCount);
            list.ForEach(f =>
            {
                f.user.roleId = f.roleId;
                f.user.organizationId = f.organizationId;
                page.Records.Add(f.user);
            });
            page.TotalCount = totalCount;
			if(loadRelevantData)
                userInfoService.Load(page.Records);

            return page;
        }

        /// <summary>
        /// 查询列表
        /// </summary>
        /// <param name="method"></param>
        /// <param name="loadRelevantData">是否加载关联数据</param>
        /// <returns></returns>
        public  List<UserApp> GetList(
            Action<ISugarQueryable<UserApp>> method,
			bool loadRelevantData = true
        )
        {
            var query = db.Queryable<UserApp>();
            method(query);
            var list = query.ToList();
			if(loadRelevantData)
				Load(list);

            return list;
        }

        /// <summary>
        /// 查询列表
        /// </summary>
        /// <param name="method"></param>
        /// <param name="loadRelevantData">是否加载关联数据</param>
        /// <returns></returns>
        public  List<UserInfo> GetList(
            Action<ISugarQueryable<UserApp, UserInfo>> method,
			bool loadRelevantData = true
        )
        {
            var query = db.Queryable<UserApp, UserInfo>((a, b) => new object[] { JoinType.Left, a.userId == b.id });
            method(query);
            var list = query.Select((a, b) => b).ToList();
			if(loadRelevantData)
                userInfoService.Load(list);

            return list;
        }


        /// <summary>
        /// 查询详情
        /// </summary>
        /// <param name="method"></param>
        /// <param name="loadRelevantData">是否加载关联数据</param>
        /// <returns></returns>
        public UserApp GetEntity(
            Action<ISugarQueryable<UserApp>> method,
			bool loadRelevantData = true
		)
        {
            var query =  db.Queryable<UserApp>();
            method(query);
            var model = query.First();
            if (loadRelevantData)
                Load(model);

            return model;
        }

        /// <summary>
        /// 查询token对象
        /// </summary>
        /// <param name="accessToken"></param>
        /// <returns></returns>
        public UserApp GetAdminUser(string accessToken)
        {
            var appId = Core.Configs.OAuthConfig.Option.DefAppId;
            var token = accessTokenService.GetEntity(
                query => query.Where(
                    a => a.scope.Equals(appId)
                        && a.accessToken.Equals(accessToken)
                        && a.expires > DateTime.Now.ToTimeStamp()
                )
            );
            if (token == null)
                throw new LogicException("access_token不存在");

            var model = GetEntity(query => query.Where(a => a.userId == token.userId.ToInt()));
            model.user = userInfoService.GetEntity(model.userId, false);
            model.user.roleId = model.roleId;
            model.user.organizationId = model.organizationId;
            userInfoService.Load(model.user);

            return model;
        }

        /// <summary>
        /// 查询用户
        /// </summary>
        /// <param name="accessToken"></param>
        /// <returns></returns>
        public UserApp GetUser(string accessToken)
        {
            var token = accessTokenService.GetEntity(
                query => query.Where(
                    a =>  a.accessToken.Equals(accessToken)
                        && a.expires > DateTime.Now.ToTimeStamp()
                )
            );
            if (token == null)
                throw new LogicException("access_token不存在");

            var model = GetEntity(query => query.Where(a => a.userId == token.userId.ToInt()));
            model.user = userInfoService.GetEntity(model.userId, false);
            model.user.roleId = model.roleId;
            model.user.organizationId = model.organizationId;
            userInfoService.Load(model.user);

            return model;
        }

        /// <summary>
        /// 根据id列表查询maps
        /// </summary>
        /// <param name="idList"></param>
        /// <returns></returns>
        public Dictionary<string, UserApp> GetMaps(List<string> idList)
        {
            var maps = new Dictionary<string, UserApp>();
            if (idList.Count < 1)
                return maps;

            var list = db.Queryable<UserApp>()
                .In(f => f.appId, idList.Distinct().ToArray())
                .ToList();

            list.ForEach(m =>
            {
                maps.Add(m.appId, m);
            });

            return maps;
        }

        /// <summary>
        /// 新增返回详情
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public UserApp CreateAt(UserApp model)
        {
            BeginTran();
            try
            {
                model.user.creatorId = model.creatorId;
                var user = userInfoService.CreateAt(model.user);

                model.createTime = DateTime.Now.ToTimeStamp();
                model.userId = user.id;
                model = db.Insertable(model).ExecuteReturnEntity();
                model.user = user;
                CommitTran();
            }
            catch (Exception e)
            {
                RollbackTran();
                throw e;
            }

            return model;
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="model"></param>
		public UserApp UpdateAt(UserApp model)
        {
            model.createTime = null;
            model.creatorId = null;
            model.loginMode = null;

            BeginTran();
            try
            {
                var rows = db.Updateable(model).IgnoreColumns(true).ExecuteCommand();
                if(model.user.NotNull())
                    userInfoService.UpdateAt(model.user);

                CommitTran();
            }
            catch (Exception e)
            {
                RollbackTran();
                throw e;
            }

			return model;
		}

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="source"></param>
        public void DeleteAt(UserApp source)
        {
             var rows = db.Deleteable<UserApp>()
                 .Where(a => a.appId.Equals(source.appId) && a.userId == source.userId)
                 .ExecuteCommand();
            if (rows < 1)
                throw new LogicException("删除失败！");
        }


		#region 加载关联数据

        public void Load(List<UserApp> list)
        {
            if (list.IsNull())
                return;

            list.ForEach(model =>
            {
                userInfoService.Load(model.user);
            });

        }

        public void Load(UserApp model)
        {
            if (model.IsNull())
                return;

            userInfoService.Load(model.user);
        }

        #endregion


    }
}
